home *** CD-ROM | disk | FTP | other *** search
/ Almathera Ten Pack 3: CDPD 3 / Almathera Ten on Ten - Disc 3: CDPD3.iso / scope / 101-125 / scopedisk106 / bbs-index / src / sort.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-03-19  |  5.7 KB  |  148 lines

  1. /*
  2.  * SORT.C
  3.  *
  4.  * This module contains the sorting routines that read sorting order from
  5.  * the command line, and sort the file database according to that order.
  6.  *
  7.  */
  8.  
  9. #ifndef LATTICE_50
  10. #include "system.h"
  11. #endif
  12.  
  13. #include "bbsindex.h"
  14.  
  15.  
  16. /*
  17.  *             Arrays used to determine sorting order for SORT.
  18.  */
  19.  
  20. int i_order[MAXINDEX+1];
  21. int i_ascend[MAXINDEX+1];
  22.  
  23.  
  24. /*
  25.  *             sortcmp()
  26.  *             ---------
  27.  *             This function is called by qsort. It compares the two specified
  28.  *             elements, and returns -ve, 0 or +ve to indicate whether the second
  29.  *             record is greater than, equal or less than the first, using the
  30.  *             sorting criteria defined in SORT.
  31.  */
  32.  
  33. /*
  34.  *             DOCMP is a macro which sets cmp equal to the value of the enclosed
  35.  *             expression if i_ascend[i] is true, or the negative of the expression
  36.  *             if i_ascend is false.
  37.  */
  38. #define DOCMP(x)       (cmp = (i_ascend[i] ? (x) : -(x)))
  39. int sortcmp(ptr1,ptr2)
  40. UDHEAD **ptr1, **ptr2;
  41. {
  42.        UDHEAD *p1 = *ptr1, *p2 = *ptr2;
  43.        int i, cmp = 0;
  44.  
  45.        /*
  46.         *              Note safety exit - last element of i_order is guaranteed == I_ANY
  47.         */
  48.        for (i = 0; !cmp; i++) {
  49.                switch (i_order[i]) {
  50.  
  51.                        case I_ANY:                     return(0);
  52.  
  53.                        case I_ACCESS:          DOCMP(p1->accesses - p2->accesses);
  54.                                                                break;
  55.                        case I_BINARY:          DOCMP(p2->bin - p1->bin);
  56.                                                                break;
  57.                        case I_COMMENT:         DOCMP(stricmp(p1->desc, p2->desc));
  58.                                                                break;
  59.                        case I_DISKNAME:        DOCMP(stricmp(p1->disk_name, p2->disk_name));
  60.                                                                break;
  61.                        case I_SECTION:         DOCMP(p1->section - p2->section);
  62.                                                                break;
  63.                        case I_ONLINE:          DOCMP(p2->online - p1->online);
  64.                                                                break;
  65.                        case I_LOCAL:           DOCMP(p2->local - p1->local);
  66.                                                                break;
  67.                        case I_NAME:            DOCMP(strcmp(p1->cat_name, p2->cat_name));
  68.                                                                break;
  69.                        case I_OWNER:           DOCMP(strcmp(p1->owner, p2->owner));
  70.                                                                break;
  71.                        case I_PATHNAME:        DOCMP(strcmp(dirnames[p1->dirnum],
  72.                                                                                         dirnames[p2->dirnum]));
  73.                                                                break;
  74.                        case I_DIRECTORY:       DOCMP(p1->dir - p2->dir);
  75.                                                                break;
  76.                        case I_DISKDIRNUM:      DOCMP(p1->dirnum - p2->dirnum);
  77.                                                                break;
  78.                        case I_VALID:           DOCMP(p2->valid - p1->valid);
  79.                                                                break;
  80.                        case I_DATE:            DOCMP(p1->date - p2->date);
  81.                                                                break;
  82.                        case I_SIZE:            DOCMP(p1->length - p2->length);
  83.                                                                break;
  84.                        case I_KSIZE:           DOCMP(BTOK(p1->length) - BTOK(p2->length));
  85.                                                                break;
  86.                }
  87.        }
  88.        return (cmp);
  89. }
  90.  
  91.  
  92. /*
  93.  *             com_sort()
  94.  *             ----------
  95.  *             This command sorts the file database into order, according to
  96.  *             the indexes specified. Each index may be optionally followed by
  97.  *             a + or - to indirect sorting direction (ascending or descending).
  98.  *             There must be no space between the direction and the +/-.
  99.  */
  100. void com_sort()
  101. {
  102.        char *index, *p;
  103.        int i, j;
  104.        int ascend;
  105.  
  106.        CHECKDATABASE();
  107.  
  108.        sorted = TRUE;
  109.        for (i = 0; i < MAXINDEX && compos < comlen; i++) {
  110.                index = getstring();
  111.                p = index + strlen(index) - 1;
  112.  
  113.                /*
  114.                 *              Now check to see if sorting direction specified, and adjust
  115.                 *              string if it was. Set 'ascend' to TRUE if ascending,
  116.                 *              else FALSE.
  117.                 */
  118.                ascend = TRUE;
  119.                if (*p == CHAR_ASCEND || *p == CHAR_DESCEND) {
  120.                        if (*p == CHAR_DESCEND)
  121.                                ascend = FALSE;
  122.                        *p = CHAR_NULL;
  123.                }
  124.  
  125.                /*
  126.                 *              Now match index, and setup appropriate entry in array
  127.                 */
  128.  
  129.                for (j = 0; j < MAXINDEX && strcmp(index,indexes[j].name); j++)
  130.                        ;
  131.                if (j == MAXINDEX) {
  132.                        scripterror("unknown index ");
  133.                        print2(index, "\n");
  134.                        Cleanup(10);
  135.                }
  136.                i_order[i]      = indexes[j].tag;
  137.                i_ascend[i]     = ascend;
  138.        }
  139.        if (i == 0) {
  140.                i_order[i] = I_NAME;
  141.                i_ascend[i++] = TRUE;
  142.        }
  143.        i_order[i] = I_ANY;
  144.  
  145.        /* Finally, do the sort! */
  146.        qsort(ptrblock, numrecs, sizeof(UDHEAD *), sortcmp);
  147. }
  148.